﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model;
//using Business.IFace;
using MB.Orm.DB;
using Public.DataAccess;
using MB.RuleBase.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;
using System.Data;
using Public;
using Dao;

namespace Business
{
    public class BOrderPick
    {
        /// <summary>
        /// 根据配送日期和批次号获取订单信息
        /// </summary>
        /// <param name="rationDate"></param>
        /// <param name="batchNumber"></param>
        /// <returns></returns>
        public List<OrderInfo> GetOrderInfo(DateTime rationDate, string batchNumber, string orderNo)
        {
            try
            {
                List<Deli_Order> lstDeli_Order = GetSqlServerDeli_OrderByCondition(rationDate.Date.ToString("yyyy-MM-dd"), batchNumber, orderNo);
                List<Deli_OrderDetail> lstDeli_OrderDetail = GetSqlServerDeli_OrderDetailByCondition(rationDate.Date.ToString("yyyy-MM-dd"), batchNumber, orderNo);

                foreach (var order in lstDeli_Order)
                {
                    order.Deli_OrderDetails = lstDeli_OrderDetail.Where(_ => _.OrderNo == order.OrderNo).ToList();
                }

                lstDeli_Order = ConvertDeli_OrderRationDateAndTime(lstDeli_Order);
                List<OrderInfo> lstOrderAPP = new List<OrderInfo>();

                List<Goods> lstGoods = OrderDao.NewInstance.GetAllGoodsInfo();
                List<MachSchemeInfo> lstMachSchemeInfo = OrderDao.NewInstance.GetMachSchemeWOW();

                List<LmSendPortArea> lstLmSendPortArea = OrderDao.NewInstance.GetLmSendPortArea();

                foreach (Deli_Order deli_Order in lstDeli_Order)
                {
                    OrderInfo _OrderAPP = new OrderInfo();
                    _OrderAPP = ConvertOrderViewToOrderInfo(deli_Order, lstGoods, lstMachSchemeInfo, lstLmSendPortArea);
                    lstOrderAPP.Add(_OrderAPP);
                }

                return lstOrderAPP;
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                return null;
            }
        }

        public List<OrderInfo> GetOrderInfo(DateTime rationDate)
        {
            try
            {
                List<OrderInfo> lstOrderDPS = new List<OrderInfo>();
                lstOrderDPS = OrderDao.NewInstance.GetOrderInfo(Convert.ToDateTime(rationDate.ToString("yyyy-MM-dd")));
                if (lstOrderDPS != null && lstOrderDPS.Count > 0)
                {
                    foreach (OrderInfo orderinfo in lstOrderDPS)
                    {
                        List<string> lstfboxs = OrderDao.NewInstance.GetFboxsByOrderNO(orderinfo.ORDERNO);
                        orderinfo.FBOXS = lstfboxs;
                    }
                }
                return lstOrderDPS;
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                return null;
            }
        }

        public List<Deli_Order> GetSqlServerDeli_OrderByCondition(string rationDate, string batchNumber, string orderNo)
        {
            using (var DbScope = new OperationDatabaseScope(new OperationDatabaseContext("MsSql")))
            {
                List<Deli_Order> _Deli_Order = new List<Deli_Order>();
                try
                {
                    _Deli_Order = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<Deli_Order>("SqlServerOrder", "GetSqlServerDeli_OrderByCondition", new object[] { rationDate, string.IsNullOrEmpty(orderNo) ? string.Empty : orderNo, string.IsNullOrEmpty(batchNumber) ? string.Empty : batchNumber });
                }
                catch (Exception ex)
                {
                    MB.Util.TraceEx.Write(ex.Message);
                }
                return _Deli_Order;
            }
        }

        public List<Deli_OrderDetail> GetSqlServerDeli_OrderDetailByCondition(string rationDate, string batchNumber, string orderNo)
        {
            using (var DbScope = new OperationDatabaseScope(new OperationDatabaseContext("MsSql")))
            {
                List<Deli_OrderDetail> _Deli_OrderDetail = new List<Deli_OrderDetail>();
                try
                {
                    _Deli_OrderDetail = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<Deli_OrderDetail>("SqlServerOrder", "GetSqlServerDeli_OrderDetailByCondition", new object[] { rationDate, string.IsNullOrEmpty(orderNo) ? string.Empty : orderNo, string.IsNullOrEmpty(batchNumber) ? string.Empty : batchNumber });
                }
                catch (Exception ex)
                {
                    MB.Util.TraceEx.Write(ex.Message);
                }
                return _Deli_OrderDetail;
            }
        }

        public List<Deli_Order> ConvertDeli_OrderRationDateAndTime(List<Deli_Order> lstDeli_Order)
        {
            List<LookupItem> lstLookupItem = new List<LookupItem>();
            //订单付款方式列表
            lstLookupItem = OrderDao.NewInstance.GetLookupItemsByLookupID("RATIONTIME");
            foreach (var order in lstDeli_Order)
            {
                if (!string.IsNullOrEmpty(order.DeliveryPeriod) && order.DeliveryPeriod.Length >= 10)
                {
                    DateTime BestDate;
                    if (DateTime.TryParse(order.DeliveryPeriod.Substring(0, 10), out BestDate))
                    {
                        order.BestDate = BestDate;
                        order.BestTime = 0;
                        LookupItem _LookupItem = (from item in lstLookupItem
                                                  where order.DeliveryPeriod.Contains(item.LOOKUP)
                                                  select item).FirstOrDefault();
                        if (_LookupItem != null)
                            order.BestTime = _LookupItem.FIELDVALUE;
                    }
                }
            }
            return lstDeli_Order;
        }

        public OrderInfo ConvertOrderViewToOrderInfo(Deli_Order deliOrder, List<Goods> lstGoods, List<MachSchemeInfo> lstMachSchemeInfo, List<LmSendPortArea> lstLmSendPortArea)
        {
            OrderInfo _OrderAPP = new OrderInfo();

            _OrderAPP.AREA = deliOrder.District;
            _OrderAPP.BATCH_NO = string.IsNullOrEmpty(deliOrder.BatchNo) ? "" : deliOrder.BatchNo;
            _OrderAPP.BATCH_SUBNO = deliOrder.BatchSubNo;
            _OrderAPP.CREATE_DATE = System.DateTime.Now;
            var sendport = lstLmSendPortArea.Where(_ => _.AREAID == deliOrder.SiteID).FirstOrDefault();
            _OrderAPP.EXLOCATION = null == sendport ? string.Empty : sendport.SENDPORTID.ToString();
            _OrderAPP.ORDERNO = deliOrder.OrderNo;
            _OrderAPP.ORDERTIME = deliOrder.OrderAddTime;
            _OrderAPP.RATIONDATE = deliOrder.BestDate;
            _OrderAPP.RATIONTIME = deliOrder.BestTime;

            List<Deli_OrderDetail> lstDeli_OrderDetail = deliOrder.Deli_OrderDetails;
            List<OrderInfoDetail> _OrderDetail = new List<OrderInfoDetail>();

            List<string> lstGOODSMACH = lstMachSchemeInfo.Select(_ => _.FORMULASN).ToList();//需拆分商品
            List<Deli_OrderDetail> lstNEED_OrderDetail = new List<Deli_OrderDetail>();
            lstNEED_OrderDetail = lstDeli_OrderDetail.Where(_ => lstGOODSMACH.Contains(_.GoodsNo)).ToList();

            //ERP配方对应W开头原料信息
            var q1 = from a in lstMachSchemeInfo
                     join b in lstGoods on a.COMBSN equals b.GOODSCODE
                     join c in lstNEED_OrderDetail on a.FORMULASN equals c.GoodsNo
                     select new
                     {
                         FORMULASN = a.FORMULASN,
                         QTY = a.QTY,
                         GOODSCODE = b.GOODSCODE,
                         PRICE = b.PRICE,
                     };
            //需拆分商品ERP中价格
            var q11 = from a in q1
                      group a by a.FORMULASN into g
                      select new
                      {
                          FORMULASN = g.Key,
                          PRICE = g.Sum(_ => _.PRICE * _.QTY),
                      };
            //拆分后商品信息
            var q111 = (from a in lstNEED_OrderDetail
                        join b in q1 on a.GoodsNo equals b.FORMULASN
                        join c in q11 on a.GoodsNo equals c.FORMULASN
                        select new
                        {
                            GoodsNo = b.GOODSCODE,
                            QTY = b.QTY * a.GoodsQty,
                            SalePrice = b.QTY * b.PRICE * a.SalePrice / c.PRICE,
                        }).Concat(from d in lstDeli_OrderDetail.Except(lstNEED_OrderDetail)
                                  select new
                                  {
                                      GoodsNo = d.GoodsNo,
                                      QTY = decimal.Parse(d.GoodsQty.ToString()),
                                      SalePrice = d.SalePrice,
                                  });
            //拆分后商品信息合并
            var qq = from a in q111
                     group a by a.GoodsNo into g
                     select new
                     {
                         GoodsNo = g.Key,
                         GoodsQty = g.Sum(_ => _.QTY),
                         SALEVALUE = g.Sum(_ => _.QTY * _.SalePrice),
                     };

            var q = from a in lstDeli_OrderDetail
                    group a by a.GoodsNo into g
                    select new
                    {
                        GoodsNo = g.Key,
                        GoodsQty = g.Sum(_ => _.GoodsQty),
                        SALEVALUE = g.Sum(_ => _.GoodsQty * _.SalePrice),
                    };

            if (lstDeli_OrderDetail != null)
            {
                List<OrderInfoDetail> lstOrderInfoDetail = new List<OrderInfoDetail>();
                foreach (var _Deli_OrderDetail in qq)
                {
                    OrderInfoDetail _OrderAPPDetail = new OrderInfoDetail();
                    Goods _Goods = lstGoods.Where(_ => _.GOODSCODE == _Deli_OrderDetail.GoodsNo).FirstOrDefault();
                    _OrderAPPDetail.QTY = _Deli_OrderDetail.GoodsQty;
                    if (_Goods != null)
                    {
                        _OrderAPPDetail.ITEMID = _Goods.GOODSID;
                        _OrderAPPDetail.ORDERNO = _OrderAPP.ORDERNO;
                        _OrderAPPDetail.DETAILNO = _OrderAPP.DETAILNO;
                        _OrderAPPDetail.ITEMCODE = _Goods.GOODSCODE;
                        _OrderAPPDetail.ITEMNAME = _Goods.GOODSNAME;
                        _OrderAPPDetail.LOCATION = _Goods.LOCATIONID.ToString();
                        lstOrderInfoDetail.Add(_OrderAPPDetail);
                    }                    
                }
                _OrderAPP.OrderInfoDetail = lstOrderInfoDetail;

            }

            return _OrderAPP;
        }

        public ResultModel WriteOrdersToDps(List<OrderInfo> orders)
        {
            var result = true;
            var message = string.Empty;
            var oracle = new MB.RuleBase.BulkCopy.SimulatedOracleHelper();
            var db = MB.Orm.Persistence.DatabaseHelper.CreateDatabase();
            var cn = oracle.CreateOracleConnection(db.ConnectionString);
            System.Data.Common.DbTransaction tran = null;

            try
            {
                cn.Open();
                tran = cn.BeginTransaction();

                using (MB.RuleBase.BulkCopy.IDbBulkExecute bulk = MB.RuleBase.BulkCopy.DbBulkExecuteFactory.CreateDbBulkExecute(tran))
                {
                    bulk.WriteToServer("Order", "InsertOrders", orders);
                }

                foreach(var order in orders)
                {
                    using (MB.RuleBase.BulkCopy.IDbBulkExecute bulk = MB.RuleBase.BulkCopy.DbBulkExecuteFactory.CreateDbBulkExecute(tran))
                    {
                        bulk.WriteToServer("Order", "InsertOrderDetails", order.OrderInfoDetail);
                    }
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                tran.Rollback();
                result = false;
                message = ex.Message;
            }
            finally
            {
                if (tran != null) tran.Dispose();
                if (cn != null) cn.Close();
                if (cn != null) cn.Dispose();
            }

            if (result)
            {
                return new ResultModel { RESULT = "1", MESSAGE = "总线写入订单到dps成功", DATA = null };
            }

            return new ResultModel { RESULT = "0", MESSAGE = "总线写入订单到dps失败"+ message + "，请联系管理员！", DATA = null };
        }

        public List<OrderInfo> GetOrderInfo(string FboxNO)
        {
            List<OrderInfo> lst = new List<OrderInfo>();
            try
            {
                string OrderNO = OrderDao.NewInstance.GetOrderNObyFboxNO(FboxNO);
                if (!string.IsNullOrEmpty(OrderNO))
                    lst = OrderDao.NewInstance.GetOrderInfo(OrderNO);
                if (lst != null && lst.Count > 0)
                {
                    foreach (OrderInfo orderinfo in lst)
                    {
                        List<OrderInfoDetail> lstDetail = OrderDao.NewInstance.GetOrderDetaillstByOrderNO(OrderNO);
                        orderinfo.OrderInfoDetail = lstDetail;
                    }
                }

                return lst;
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                return null;
            }
        }

        public bool ChangeDPSOrderStatus(string OrderNO,int Status)
        {
            try
            {
                var _result = OrderDao.NewInstance.UpdatePindentStatus(Status, OrderNO);//复核订单后状态变为2已复核，1为已绑定
                return _result;
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                return false;
            }
        }

        public List<OrderInfo> GetOrderInfobyOrderNO(string OrderNO)
        {
            List<OrderInfo> lst = new List<OrderInfo>();
            try
            {
                lst = OrderDao.NewInstance.GetOrderInfo(OrderNO);
                if (lst != null && lst.Count > 0)
                {
                    foreach (OrderInfo orderinfo in lst)
                    {
                        List<string> lstfboxs = OrderDao.NewInstance.GetFboxsByOrderNO(OrderNO);
                        orderinfo.FBOXS = lstfboxs;
                        List<OrderInfoDetail> lstDetail = OrderDao.NewInstance.GetOrderDetaillstByOrderNO(OrderNO);
                        orderinfo.OrderInfoDetail = lstDetail;
                    }
                }

                return lst;
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                return null;
            }
        }

        public string GetOrderNOByFboxNo(string FboxNO)
        {
            return OrderDao.NewInstance.GetOrderNObyFboxNO(FboxNO);
        }

        public DataSet GetFrozenGoodsInfo(DateTime rationDate, string batchNumber)
        {


            try
            {
                return DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("Order", "GetFrozenGoodsInfo", new object[] { rationDate.Date.ToString("yyyy-MM-dd"), batchNumber });
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                if (ex.Message.Contains("ORA-03135"))
                {
                    return DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("Order", "GetFrozenGoodsInfo", new object[] { rationDate.Date.ToString("yyyy-MM-dd"), batchNumber });
                }
                return null;
            }
        }

        /// <summary>
        /// 根据配送日期、批次号、商品编码获取数量统计信息
        /// </summary>
        /// <param name="rationDate"></param>
        /// <param name="BatchNO"></param>
        /// <param name="GoodsCode"></param>
        /// <returns></returns>
        public DataSet GetSumOrderItem(string rationDate, string BatchNO, string GoodsCode)
        {
            try
            {

                DataSet ds = DatabaseExcuteByXmlHelper.NewInstance.GetDataSetByXml("Order", "GetPickSUMOrderItemqty", new object[]{rationDate, BatchNO, GoodsCode});
                return ds;
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                return null;
            }
        }

        /// <summary>
        /// 根据订单号查询配送系统的订单信息
        /// </summary>
        /// <param name="orderNo"></param>
        /// <returns></returns>
        public ResultModel CheckOrderIsChanged(DateTime rationDate, string OrderNO)
        {
            bool _result = true;
            string _message = "";
            try
            {
                using (var DbScope = new OperationDatabaseScope(new OperationDatabaseContext("MsSql")))
                {
                    List<Deli_Order> _Deli_Order = new List<Deli_Order>();
                    _Deli_Order = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<Deli_Order>("SqlServerOrder", "GetSqlServerDeli_OrderByOrderNo", OrderNO);

                    if (_Deli_Order == null || _Deli_Order.Count <= 0)
                    {
                        return new ResultModel { RESULT = "1", MESSAGE = "找不到订单信息！", DATA = null };
                    }

                    var deliOrder = _Deli_Order.FirstOrDefault();

                    //if (string.IsNullOrEmpty(deliOrder.BatchDeliveryPeriodHis)
                    //    || string.IsNullOrEmpty(deliOrder.ProvinceHis)
                    //    || string.IsNullOrEmpty(deliOrder.CityHis)
                    //    || string.IsNullOrEmpty(deliOrder.DistrictHis)
                    //    || string.IsNullOrEmpty(deliOrder.AddressHis))
                    //{
                    //    return new ResultModel { RESULT = "1", MESSAGE = "订单未分拣！", DATA = null };
                    //}

                    if (deliOrder.OrderStatus == 2)
                    {
                        return new ResultModel { RESULT = "1", MESSAGE = "订单已取消！", DATA = null };
                    }
                    if (string.IsNullOrEmpty(deliOrder.BatchDeliveryPeriodHis))
                    {
                        deliOrder.BatchDeliveryPeriodHis = "";
                    }
                    
                    if (deliOrder.BatchDeliveryPeriodHis.Length>=11 && deliOrder.DeliveryPeriod.Length>=11 &&!deliOrder.BatchDeliveryPeriodHis.Replace(" ", "").Substring(0, 10).Equals(deliOrder.DeliveryPeriod.Replace(" ", "").Substring(0, 10)))
                    {
                        return new ResultModel { RESULT = "1", MESSAGE = string.Format("订单的配送时间已发生变化：（原配送时间：{0}改为：{1}）,请修改配送时间重新核单！", deliOrder.BatchDeliveryPeriodHis, deliOrder.DeliveryPeriod), DATA = null };
                    }
                    if (!deliOrder.DeliveryPeriod.Replace(" ", "").Substring(0, 10).Equals(rationDate.ToString("yyyy-MM-dd")))
                    {
                        return new ResultModel { RESULT = "1", MESSAGE = string.Format("配送时间不匹配：（订单配送时间：{0}）,请修改配送时间核单！", deliOrder.DeliveryPeriod), DATA = null };
                    }
                    //if (!deliOrder.Province.Replace(" ", "").Equals(deliOrder.ProvinceHis.Replace(" ", ""))
                    //    || !deliOrder.City.Replace(" ", "").Equals(deliOrder.CityHis.Replace(" ", ""))
                    //    || !deliOrder.District.Replace(" ", "").Equals(deliOrder.DistrictHis.Replace(" ", ""))
                    //    || !deliOrder.Address.Replace(" ", "").Equals(deliOrder.AddressHis.Replace(" ", "")))
                    //{
                    //    return new ResultModel { RESULT = "1", MESSAGE = string.Format("订单的配送地址已发生变化！（原配送地址：{0}{1}改为：{2}{3}）", deliOrder.DistrictHis, deliOrder.AddressHis, deliOrder.District, deliOrder.Address), DATA = null };
                    //}

                    return new ResultModel { RESULT = "0", MESSAGE = "订单信息未发生变化！", DATA = null };

                }
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                _message = ex.Message;
                _result = false;
            }

            if (!_result)
                return new ResultModel { RESULT = "1", MESSAGE = "判断订单的状态失败！：" + _message, DATA = null };
            else
                return new ResultModel { RESULT = "0", MESSAGE = "订单信息未发生变化！", DATA = null };
        }

        public ResultModel CheckFboxIsChanged(string FBOXNO)
        {
            bool _result = true;
            string _message = "";
            try
            {
                string OrderNO = GetOrderNOByFboxNo(FBOXNO);
                if (string.IsNullOrEmpty(OrderNO))
                {
                    return new ResultModel { RESULT = "1", MESSAGE = "发货箱未绑订单,可以使用！", DATA = null };
                }
                using (var DbScope = new OperationDatabaseScope(new OperationDatabaseContext("MsSql")))
                {
                    List<Deli_Order> _Deli_Order = new List<Deli_Order>();
                    _Deli_Order = DatabaseExcuteByXmlHelper.NewInstance.GetObjectsByXml<Deli_Order>("SqlServerOrder", "GetSqlServerDeli_OrderByOrderNo", OrderNO);

                    if (_Deli_Order == null || _Deli_Order.Count <= 0)
                    {
                        return new ResultModel { RESULT = "0", MESSAGE = "配送系统找不到订单:" + OrderNO + "信息！", DATA = null };
                    }

                    var deliOrder = _Deli_Order.FirstOrDefault();

                    if (deliOrder.OrderStatus == 2 || deliOrder.OrderStatus == 4 || deliOrder.OrderStatus == 8 || deliOrder.DeliveryStatus == 5)//订单状态为2取消4退货8退款-配送状态5送达
                    {
                        return new ResultModel { RESULT = "1", MESSAGE = "订单:" + OrderNO + "任务结束,发货箱可以使用！", DATA = null };
                    }
                    else
                    {
                        List<P_INDENT_CHECK_HIS> lst = OrderDao.NewInstance.GetOrderCheckHisInfo(OrderNO, FBOXNO);
                        if (lst != null && lst.Count > 0 && (DateTime.Now - lst[0].CHECKDATE).Hours >= 24)
                        {
                            return new ResultModel { RESULT = "1", MESSAGE = "核单超过24小时,发货箱可以使用！", DATA = null };
                        }
                        else
                        {
                            return new ResultModel { RESULT = "0", MESSAGE = "订单任务未结束,发货箱不可以使用！", DATA = null };
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                _message = ex.Message;
                _result = false;
            }

            if (!_result)
                return new ResultModel { RESULT = "0", MESSAGE = "判断发货箱状态失败！：" + _message, DATA = null };
            else
                return new ResultModel { RESULT = "1", MESSAGE = "发货箱可以使用！", DATA = null };
        }

        public bool CheckHistoryLog(string ORDERNO, string FBOXNO, int USERID, string USERNAME,string CHECKLOCATION)
        {
            try
            {
                var _result = OrderDao.NewInstance.CheckhistoryLog(ORDERNO, FBOXNO, USERID, USERNAME,CHECKLOCATION, DateTime.Now);//复核历史记录
                return _result;
            }
            catch (Exception ex)
            {
                MB.Util.TraceEx.Write(ex.Message);
                return false;
            }
        }

        public List<FinishedOrderInfo> GetOrderFinishedInfoList(DateTime rationdate, string BatchNO, int BeginSubNO, int EndSubNO)
        {
            return OrderDao.NewInstance.GetBatchFinishedOrderList(rationdate, BatchNO, BeginSubNO, EndSubNO);
        }

        /// <summary>
        /// 根据商品编号和侧扫口及侧扫口左侧或右侧，查找该侧扫口订单需要该商品的总数量
        /// </summary>
        /// <param name="goodsSn"></param>
        /// <param name="sideSweep"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public DataSet GetTotalGoodsBySn(string goodsSn, int sideSweep, int right)
        {
            return OrderDao.NewInstance.GetTotalGoodsBySn(goodsSn, sideSweep, right);
        }
    }
}
